/**
 * { data-analysis:  ['read', 'write'] }
 */

export type UserPermission = Record<string, string[]>; // 用户权限类型：映射资源名称到允许的操作数组

type Auth = {
  resource: string | RegExp; // 资源，可以是字符串或正则表达式
  actions?: string[]; // 关联的操作数组
};

export interface AuthParams {
  requiredPermissions?: Array<Auth>; // 所需的权限数组
  oneOfPerm?: boolean; // 是否只需满足其中一个权限
}

// 检查用户的权限是否包括所请求的操作
const judge = (actions: string[], perm: string[]) => {
  if (!perm || !perm.length) {
    return false; // 如果没有权限，返回false
  }

  if (perm.join('') === '*') {
    return true; // 如果权限是“*”，表示所有操作都被允许
  }

  return actions.every((action) => perm.includes(action)); // 检查所有请求的操作是否都在权限中
};

// 验证用户对特定资源的权限
const auth = (params: Auth, userPermission: UserPermission) => {
  const { resource, actions = [] } = params; // 解构资源和操作
  if (resource instanceof RegExp) {
    // 如果资源是正则表达式
    const permKeys = Object.keys(userPermission); // 获取用户权限的所有键
    const matchPermissions = permKeys.filter((item) => item.match(resource)); // 匹配正则表达式的权限键
    if (!matchPermissions.length) {
      return false; // 如果没有匹配的权限，返回false
    }
    return matchPermissions.every((key) => {
      const perm = userPermission[key]; // 获取匹配权限的操作
      return judge(actions, perm); // 使用judge函数验证操作
    });
  }

  const perm = userPermission[resource]; // 获取特定资源的权限
  return judge(actions, perm); // 使用judge函数验证操作
};

// 主导函数，验证所需权限
export default (params: AuthParams, userPermission: UserPermission) => {
  const { requiredPermissions, oneOfPerm } = params; // 解构所需权限和oneOfPerm标志
  if (Array.isArray(requiredPermissions) && requiredPermissions.length) {
    let count = 0; // 计数已满足的权限数量
    for (const rp of requiredPermissions) {
      // 遍历所有所需权限
      if (auth(rp, userPermission)) {
        // 检查用户是否满足当前权限
        count++; // 满足时计数加1
      }
    }
    // 根据oneOfPerm标志返回结果
    return oneOfPerm ? count > 0 : count === requiredPermissions.length;
  }
  return true; // 如果没有所需权限，默认返回true
};

